package com.x.component.hardware;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.UUID;

import com.x.component.connectivity.FrameworkServicesModule;
import com.x.component.hardware.ProcStatsData.MemInfo;
import com.x.component.hardware.ProcStatsData.RomInfo;

import android.app.usage.StorageStats;
import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.StatFs;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;

public class SocComponent {

	private static SocComponent mInstance = null;

	private static final Object mLock = new Object();

	private Context mContext;
	
	private HandlerThread mInstallThread;
	private Handler mInstallHandler;

	private StorageStatsManager mStorageStatsManager;

	private StorageManager mStorageManager;

	private SocComponent() {
		mInstallThread = new HandlerThread("MediaWidgetHostThread");
		mInstallThread.start();
		mInstallHandler = new Handler(mInstallThread.getLooper()) {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				switch (msg.what) {
				case 0:
					break;

				default:
					break;
				}
			}
		};
	}

	public static SocComponent getInstance() {
		if (null == mInstance) {
			synchronized (mLock) {
				if (null == mInstance) {
					mInstance = new SocComponent();
				}
			}
		}
		return mInstance;
	}

	public void init(Context context) {
		this.mContext = context;

	}

	public String[] getCPUModel() {
		String[] info = new String[2];
		String type = SystemProperties.get("ro.soc.model", "");
		if ("SM6125".equalsIgnoreCase(type)) {
			info[0] = "SM6125";
			info[1] = "665";
		} else if ("SM6225".equalsIgnoreCase(type)) {
			info[0] = "SM6225";
			info[1] = "680";
		}
		return info;
	}

	// CPU的温度
	public float[] getCPUTemperatures(Context context, int cores) {
		getCPUTemperaturesByTask(context, cores);
		return new float[8];
	}
	
	// CPU的温度
	private void getCPUTemperaturesByTask(final Context context, final int cores) {
		mInstallHandler.post(new Runnable() {
			
			@Override
			public void run() {
				String command;
				String thermal;
				
				try {
					// 7 8 9 10 11 12 13 14依次代表8个核心
					if (cores == 8) {// 622平台8核心
						// 执行 "/sys/devices/virtual/thermal/thermal_zone7/temp" 指令可以读取到核心1的温度
						String type = SystemProperties.get("ro.soc.model", "");
						String bwm_type = SystemProperties.get("ro.build.customer", "");// applepiewl表示宝马无线版本2024 04 12
						if ((type != null && !TextUtils.isEmpty(type) && type.equals("SM6125"))
								|| (bwm_type != null && !TextUtils.isEmpty(bwm_type) && bwm_type.equals("applepiewl"))) {
							
							float[] cpuTemps = new float[8];
							// for (int i = 7; i <= 14; i++) {
							for (int i = 11; i <= 29; i++) {
								thermal = "thermal_zone" + i;
								command = "/sys/devices/virtual/thermal/" + thermal + "/temp";
								String line = CpuFrequencyReader.readFileSystem(command);
								if (line != null && i == 11) {
									float temp = Float.parseFloat(line) / 1000.0f;
									// cpuTemps[i - 7] = temp;
									cpuTemps[0] = temp;// 测试，核心1的温度
								} else if (line != null
										&& (i == 23 || i == 24 || i == 25 || i == 26 || i == 27 || i == 28 || i == 29)) {
									float temp = Float.parseFloat(line) / 1000.0f;
									cpuTemps[i - 22] = temp;
									
									// cpuTemps[i - 7] = 53.2f;
								} else {
									continue;
								}
								
							}
							return;
						} else if (type != null && !TextUtils.isEmpty(type) && type.equals("FBSM6125")) {// 广和通
							float[] cpuTemps = new float[8];
							for (int i = 1; i <= 17; i++) {
								thermal = "thermal_zone" + i;
								command = "/sys/devices/virtual/thermal/" + thermal + "/temp";
								String line = CpuFrequencyReader.readFileSystem(command);
								if (line != null && i == 1) {
									float temp = Float.parseFloat(line) / 1000.0f;
									// cpuTemps[i - 7] = temp;
									cpuTemps[0] = temp;// 测试，核心1的温度
								} else if (line != null
										&& (i == 11 || i == 12 || i == 13 || i == 14 || i == 15 || i == 16 || i == 17)) {
									float temp = Float.parseFloat(line) / 1000.0f;
									cpuTemps[i - 10] = temp;
									// cpuTemps[i - 7] = 53.2f;
								} else {
									continue;
								}
								
							}
							return;
							
						} else if (type != null && !TextUtils.isEmpty(type) && type.equals("SM7325")) {// 新加的类型2023 03 16
							float[] cpuTemps = new float[8];
							for (int i = 21; i <= 28; i++) {
								thermal = "thermal_zone" + i;
								command = "/sys/devices/virtual/thermal/" + thermal + "/temp";
								String line = CpuFrequencyReader.readFileSystem(command);
								if (line != null) {
									float temp = Float.parseFloat(line) / 1000.0f;
									cpuTemps[i - 21] = temp;
								} else {
									cpuTemps[i - 21] = 53.2f;
								}
								
							}
							return;
							
						} else {// 普通读取方法2023 02 27
							float[] cpuTemps = new float[8];
							for (int i = 7; i <= 14; i++) {
								thermal = "thermal_zone" + i;
								command = "/sys/devices/virtual/thermal/" + thermal + "/temp";
								String line = CpuFrequencyReader.readFileSystem(command);
								if (line != null) {
									float temp = Float.parseFloat(line) / 1000.0f;
									cpuTemps[i - 7] = temp;
								} else {
									cpuTemps[i - 7] = 53.2f;
								}
								
							}
							return;
						}
					} else if (cores == 4) {// 2290平台4核心
						// 4核心单独读取
						float[] cpuTemps = new float[4];
						for (int i = 7; i <= 10; i++) {
							thermal = "thermal_zone" + i;
							command = "/sys/devices/virtual/thermal/" + thermal + "/temp";
							String line = CpuFrequencyReader.readFileSystem(command);
							if (line != null) {
								float temp = Float.parseFloat(line) / 1000.0f;
								// Log.d("CPUTemps", i + " Temperatures: " + temp);
								cpuTemps[i - 7] = temp;
								// return temp / 1000.0f;
							} else {
								// return 51.4f;
								cpuTemps[i - 7] = 53.2f;
							}
						}
						return;
					}
				} catch (Exception e) {
					e.printStackTrace();
					// return 53.6f;
					
				}
				
			}
		});
	}
	
	

	public int availableProcessors() {
		return Runtime.getRuntime().availableProcessors();
	}

	public String readMaxCpuFrequency() {
		return CpuFrequencyReader.readMaxCpuFrequency();
	}

	public String readMinCpuFrequency() {
		return CpuFrequencyReader.readMinCpuFrequency();
	}

	public String readCurrentCpuFrequency() {
		return CpuFrequencyReader.readCurrentCpuFrequency();
	}

	public MemInfo getCpuRamInfo() {
		ProcStatsData mProcStatsData = new ProcStatsData(mContext, false);
		mProcStatsData.refreshStats(true);
		MemInfo memInfo = mProcStatsData.getMemInfo();

		final Formatter.BytesResult result = Formatter.formatBytes(mContext.getResources(), (long) memInfo.realTotalRam,
				Formatter.FLAG_SHORTER);
		final Formatter.BytesResult resultFree = Formatter.formatBytes(mContext.getResources(),
				(long) memInfo.realFreeRam, Formatter.FLAG_SHORTER);
		final Formatter.BytesResult resultUsed = Formatter.formatBytes(mContext.getResources(),
				(long) memInfo.realUsedRam, Formatter.FLAG_SHORTER);

		memInfo.uiTotalRam = result.value;
		memInfo.uiFreeRam = resultFree.value;
		memInfo.uiUsedRam = resultUsed.value;
		return memInfo;
	}

	public RomInfo getDeviceRomInfo() {
		mStorageStatsManager = FrameworkServicesModule.provideStorageStatsManager(mContext);
		mStorageManager = FrameworkServicesModule.provideStorageManager(mContext);
		long totalSize = 0;
		RomInfo info = new RomInfo(mContext);
		try {
			VolumeInfo volumeInfo = mStorageManager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
			totalSize = mStorageStatsManager.getTotalBytes(volumeInfo.getFsUuid());
			info.realTotalRom = totalSize;
			final Formatter.BytesResult result = Formatter.formatBytes(mContext.getResources(), totalSize,
					Formatter.FLAG_SHORTER);
			info.totalRom = result.value;
			Log.d("TinkerSoc", "getDeviceRomInfo totalSize: " + totalSize);
			Log.d("TinkerSoc", "getDeviceRomInfo totalSize: " + result.value);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long availableSize = 0;
		try {
			VolumeInfo volumeInfo = mStorageManager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
			availableSize = mStorageStatsManager.getFreeBytes(volumeInfo.getFsUuid());
			long usedSize = totalSize - availableSize;
			info.realFreeRom = availableSize;
			info.realUsedRom = usedSize;
			final Formatter.BytesResult resultFree = Formatter.formatBytes(mContext.getResources(), availableSize,
					Formatter.FLAG_SHORTER);
			final Formatter.BytesResult resultUsed = Formatter.formatBytes(mContext.getResources(), usedSize,
					Formatter.FLAG_SHORTER);
			Log.d("TinkerSoc", "getDeviceRomInfo availableSize: " + availableSize);
			Log.d("TinkerSoc", "getDeviceRomInfo availableSize: " + resultFree.value);
			Log.d("TinkerSoc", "getDeviceRomInfo usedSize: " + resultUsed.value);
			info.freeRom = resultFree.value;
			info.usedRom = resultUsed.value;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return info;
	}

	public double getCacheFileSize() {
		// 获取缓存目录文件大小并转换为MB
		long cacheSize = getTotalCacheSize(mContext);
		double cacheSizeInMB = cacheSize / (1024.0 * 1024.0);
		// 输出缓存大小
		Log.d("CacheSize", "Cache Size: " + cacheSizeInMB + " MB");
		return cacheSizeInMB;
	}

    private long getTotalCacheSize(Context context) {
    	 long totalCacheSize = 0;
        PackageManager pm = context.getPackageManager();
        List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
        StorageStatsManager storageStatsManager = (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);
        StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
		try {
			UUID  defaultUUID = storageManager.getUuidForPath(context.getFilesDir());
	        for (ApplicationInfo packageInfo : packages) {
	            try {
	                StorageStats storageStats = storageStatsManager.queryStatsForPackage(defaultUUID, packageInfo.packageName, UserHandle.SYSTEM);
	                totalCacheSize += storageStats.getCacheBytes();
	            } catch (Exception e) {
	                // Ignore errors for packages that cannot be queried
	                e.printStackTrace();
	            }
	        }
		} catch (Exception e1) {
			e1.printStackTrace();
		}
        return totalCacheSize;
    }

}
